package com.example.xmpic.ui.activity.setting;

import android.content.Intent;
import android.os.Message;
import android.view.View;
import android.widget.SeekBar;

import com.basic.G;
import com.example.common.base.BaseBindActivity;
import com.example.xmpic.R;
import com.example.xmpic.databinding.ActivitySetAlarmBinding;
import com.example.xmpic.support.FunError;
import com.example.xmpic.support.FunSupport;
import com.example.xmpic.support.OnFunDeviceOptListener;
import com.example.xmpic.support.config.AlarmOut;
import com.example.xmpic.support.config.DetectBlind;
import com.example.xmpic.support.config.DetectMotion;
import com.example.xmpic.support.models.FunDevice;
import com.example.xmpic.support.utils.DeviceConfigType;
import com.example.xmpic.ui.adapter.OptionAdapter;
import com.lib.DevSDK;
import com.lib.EUIMSG;
import com.lib.FunSDK;
import com.lib.IFunSDKResult;
import com.lib.MsgContent;
import com.lib.sdk.bean.HandleConfigData;
import com.lib.sdk.bean.JsonConfig;
import com.lib.sdk.bean.NetworkPmsBean;
import com.lib.sdk.struct.H264_DVR_FILE_DATA;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author skygge
 * @Date on 2020-02-28.
 * GitHub：javofxu@github.com
 * email：skygge@yeah.net
 * description：摄像头报警设置
 */
public class CameraSetAlarmActivity extends BaseBindActivity<ActivitySetAlarmBinding> implements OnFunDeviceOptListener, IFunSDKResult {

    private int mUserId;
    private int mDeviceId;
    private boolean openMode = false;
    private boolean openInterval = false;

    private FunDevice mFunDevice = null;

    private final String[] DEV_CONFIGS = {
            //移动侦测
            DetectMotion.CONFIG_NAME,

            //视频遮挡
            DetectBlind.CONFIG_NAME,
            AlarmOut.CONFIG_NAME
    };

    // 设置配置信息的时候,由于有多个,通过下面的列表来判断是否所有的配置都设置完成了
    private final List<String> mSettingConfigs = new ArrayList<>();

    private String[] item;
    private ArrayList<String> items;
    private NetworkPmsBean mNetworkPms;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_set_alarm;
    }

    @Override
    protected void initialize() {
        super.initialize();
        mDeviceId = getIntent().getIntExtra("FUN_DEVICE_ID", 0);
        mFunDevice = FunSupport.getInstance().findDeviceById(mDeviceId);
        if ( null == mFunDevice ) {
            finish();
        }
    }

    @Override
    protected void initView() {
        super.initView();
        items = new ArrayList<>();
        // 注册设备操作监听
        FunSupport.getInstance().registerOnFunDeviceOptListener(this);
        // 获取报警配置信息
        tryGetAlarmConfig();
    }

    @Override
    protected void initData() {
        super.initData();
        item = getResources().getStringArray(R.array.device_setup_alarm_level);
        items.addAll(Arrays.asList(item));
        mDBind.setSensitivity.setAdapter(new OptionAdapter(items, 150));
    }

    @Override
    protected void initListener() {
        super.initListener();
        mDBind.ivAlarmBack.setOnClickListener(v -> finish());
        mDBind.tvSaveSet.setOnClickListener(view -> trySaveAlarmConfig());
        mDBind.openAlarm.setOnClickListener(view -> view.setSelected(!view.isSelected()));
        mDBind.openVideo.setOnClickListener(view -> view.setSelected(!view.isSelected()));
        mDBind.openPicture.setOnClickListener(view -> view.setSelected(!view.isSelected()));
        mDBind.alarmPeriod.setOnClickListener(v -> {
            Intent intent = new Intent(mContext, CameraAlarmPeriodActivity.class);
            intent.putExtra("FUN_DEVICE_ID", mDeviceId);
            startActivity(intent);
        });
        mDBind.alarmType.setOnClickListener(view -> {
            if (openMode){
                mDBind.alarmType.setShowArrow(false);
                mDBind.setMode.setVisibility(View.GONE);
            }else {
                mDBind.alarmType.setShowArrow(true);
                mDBind.setMode.setVisibility(View.VISIBLE);
            }
            openMode = !openMode;
        });
        mDBind.alarmInterval.setOnClickListener(view -> {
            if (openInterval){
                mDBind.alarmType.setShowArrow(false);
                mDBind.setInterval.setVisibility(View.GONE);
            }else {
                mDBind.alarmType.setShowArrow(true);
                mDBind.setInterval.setVisibility(View.VISIBLE);
            }
        });
        mDBind.alarmSensitivity.setOnClickListener(view -> {
            mDBind.alarmShow.setVisibility(View.VISIBLE);
        });
        mDBind.tvSaveNum.setOnClickListener(view -> {
            mDBind.alarmShow.setVisibility(View.GONE);
            mDBind.alarmSensitivity.setDetailText(item[mDBind.setSensitivity.getCurrentItem()]);
        });
        mDBind.tvCancel.setOnClickListener(view -> mDBind.alarmShow.setVisibility(View.GONE));
        mDBind.alarmSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                if (b){
                    mNetworkPms.PushInterval = i;
                    mDBind.alarmInterval.setDetailText(i + "s");
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    private void trySaveAlarmConfig(){

        boolean beMotionChanged = false;

        DetectMotion detectMotion = (DetectMotion)mFunDevice.getConfig(DetectMotion.CONFIG_NAME);
        if ( null != detectMotion ) {
            if (mDBind.openAlarm.isSelected() != detectMotion.Enable ) {
                detectMotion.Enable = mDBind.openAlarm.isSelected();
                beMotionChanged = true;
            }

            if (mDBind.openVideo.isSelected() != detectMotion.event.RecordEnable ) {
                detectMotion.event.RecordEnable = mDBind.openVideo.isSelected();
                detectMotion.event.RecordMask = DevSDK.SetSelectHex(
                        detectMotion.event.RecordMask, mFunDevice.CurrChannel,
                        detectMotion.event.RecordEnable);
                beMotionChanged = true;
            }

            if (mDBind.openPicture.isSelected() != detectMotion.event.SnapEnable ) {
                detectMotion.event.SnapEnable = mDBind.openPicture.isSelected();
                detectMotion.event.SnapShotMask = DevSDK.SetSelectHex(
                        detectMotion.event.SnapShotMask, mFunDevice.CurrChannel,
                        detectMotion.event.SnapEnable);
                beMotionChanged = true;
            }

            if (mDBind.setSensitivity.getCurrentItem() != changeLevelToUI(detectMotion.Level) ) {
                detectMotion.Level = changeLevelToDetect(mDBind.setSensitivity.getCurrentItem());
                beMotionChanged = true;
            }

            if (mNetworkPms != null) {
                beMotionChanged = true;
                FunSDK.DevCmdGeneral(mUserId, mFunDevice.getDevSn(), 1040, JsonConfig.CFG_PMS, -1, 5000,
                        HandleConfigData.getSendData(JsonConfig.CFG_PMS,"0x08", mNetworkPms).getBytes(), -1, 0);
            }
        }


        mSettingConfigs.clear();

        if (beMotionChanged) {
            showProgressDialog();
            synchronized (mSettingConfigs) {
                mSettingConfigs.add(detectMotion.getConfigName());
            }
            FunSupport.getInstance().requestDeviceSetConfig(mFunDevice, detectMotion);
        }
    }

    private void tryGetAlarmConfig() {
        if ( null != mFunDevice ) {
            mUserId = FunSDK.GetId(mUserId,this);
            showProgressDialog();
            for ( String configName : DEV_CONFIGS ) {
                // 删除老的配置信息
                mFunDevice.invalidConfig(configName);
                // 重新搜索新的配置信息
                if (contains(DeviceConfigType.DeviceConfigCommon, configName)) {
                    FunSupport.getInstance().requestDeviceConfig(mFunDevice,
                            configName);
                }else if (contains(DeviceConfigType.DeviceConfigByChannel, configName)) {
                    FunSupport.getInstance().requestDeviceConfig(mFunDevice, configName, mFunDevice.CurrChannel);
                }
            }

            //获取报警间隔
            FunSDK.DevCmdGeneral(mUserId, mFunDevice.getDevSn(), 1042,
                    JsonConfig.CFG_PMS, -1, 5000, null, -1, 0);
        }
    }

    private void refreshAlarmConfig() {
        DetectMotion detectMotion = (DetectMotion)mFunDevice.getConfig(DetectMotion.CONFIG_NAME);
        if ( null != detectMotion ) {
            mDBind.openAlarm.setSelected(detectMotion.Enable);
            mDBind.openVideo.setSelected(detectMotion.event.RecordEnable);
            mDBind.openPicture.setSelected(detectMotion.event.SnapEnable);
            mDBind.setSensitivity.setCurrentItem(changeLevelToUI(detectMotion.Level));
            mDBind.alarmSensitivity.setDetailText(item[changeLevelToUI(detectMotion.Level)]);
        }
    }

    private boolean isCurrentUsefulConfig(String configName) {
        for ( int i = 0; i < DEV_CONFIGS.length; i ++ ) {
            if ( DEV_CONFIGS[i].equals(configName) ) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否所有需要的配置都获取到了
     * @return
     */
    private boolean isAllConfigGetted() {
        for ( String configName : DEV_CONFIGS ) {
            if ( null == mFunDevice.getConfig(configName) ) {
                return false;
            }
        }
        return true;
    }

    /**
     *  判断某个字符串是否存在于数组中
     *  用来判断该配置是否通道相关
     *  @param stringArray 原数组
     *  @param source 查找的字符串
     *  @return 是否找到
     */
    private boolean contains(String[] stringArray, String source) {
        // 转换为list
        List<String> tempList = Arrays.asList(stringArray);

        // 利用list的包含方法,进行判断
        return tempList.contains(source);
    }
    /**
     * Level报警灵敏度转换,界面低级/中级/高级(0,1,2),需要和实际级别做一个转换
     * @param level
     * @return
     */
    private int changeLevelToUI(int level) {
        int uiLevel = (level == 0 ? 1 : (level % 2 + level / 2)) - 1;
        return Math.max(0, uiLevel);
    }

    private int changeLevelToDetect(int uiLevel) {
        return (uiLevel+1) * 2;
    }

    @Override
    public void onDeviceLoginSuccess(FunDevice funDevice) {

    }

    @Override
    public void onDeviceLoginFailed(FunDevice funDevice, Integer errCode) {

    }

    @Override
    public void onDeviceGetConfigSuccess(FunDevice funDevice, String configName, int nSeq) {
        if ( null != mFunDevice && funDevice.getId() == mFunDevice.getId()
                && isCurrentUsefulConfig(configName) ) {
            if ( isAllConfigGetted() ) {
                dismissProgressDialog();
            }

            refreshAlarmConfig();
        }
    }

    @Override
    public void onDeviceGetConfigFailed(FunDevice funDevice, Integer errCode) {
        dismissProgressDialog();
        showToast(FunError.getErrorStr(errCode));
    }

    @Override
    public void onDeviceSetConfigSuccess(FunDevice funDevice, String configName) {
        if ( null != mFunDevice && funDevice.getId() == mFunDevice.getId() ) {
            synchronized (mSettingConfigs) {
                if ( mSettingConfigs.contains(configName) ) {
                    mSettingConfigs.remove(configName);
                }

                if ( mSettingConfigs.size() == 0 ) {
                    // 所有的设置修改都已经完成
                    dismissProgressDialog();
                    showToast(getString(R.string.success));
                    finish();
                }
            }

            refreshAlarmConfig();
        }
    }

    @Override
    public void onDeviceSetConfigFailed(FunDevice funDevice, String configName, Integer errCode) {
        showToast(FunError.getErrorStr(errCode));
    }

    @Override
    public void onDeviceChangeInfoSuccess(FunDevice funDevice) {

    }

    @Override
    public void onDeviceChangeInfoFailed(FunDevice funDevice, Integer errCode) {

    }

    @Override
    public void onDeviceOptionSuccess(FunDevice funDevice, String option) {

    }

    @Override
    public void onDeviceOptionFailed(FunDevice funDevice, String option, Integer errCode) {

    }

    @Override
    public void onDeviceFileListChanged(FunDevice funDevice) {

    }

    @Override
    public void onDeviceFileListChanged(FunDevice funDevice, H264_DVR_FILE_DATA[] datas) {

    }

    @Override
    public void onDeviceFileListGetFailed(FunDevice funDevice) {

    }

    @Override
    public int OnFunSDKResult(Message message, MsgContent msgContent) {
        if (message.what == EUIMSG.DEV_CMD_EN) {
            if (JsonConfig.CFG_PMS.equals(msgContent.str)) {
                if (msgContent.pData != null) {
                    HandleConfigData configData = new HandleConfigData();
                    if (configData.getDataObj(G.ToString(msgContent.pData), NetworkPmsBean.class)) {
                        mNetworkPms = (NetworkPmsBean) configData.getObj();
                        if (mNetworkPms != null) {
                            mDBind.alarmSeekBar.setProgress(mNetworkPms.PushInterval);
                            mDBind.alarmInterval.setDetailText(mNetworkPms.PushInterval + "s");
                        }
                    }
                } else {
                    showToast(getString(R.string.ota_get_info_error));
                }
            }
        }
        return 0;
    }


    @Override
    protected void onDestroy() {
        // 注销监听
        FunSupport.getInstance().removeOnFunDeviceOptListener(this);
        super.onDestroy();
    }
}
